/*
 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_i2c.h"
#include "iot_gpio.h"
#include "iot_errno.h"

#include "oled_ssd1306.h"
#include "app_demo_uart.h"
#include <hi_stdlib.h>
#include <hi_uart.h>
#include <iot_uart.h>
#include <hi_gpio.h>
#include <hi_io.h>
#include "iot_gpio_ex.h"

#include "iot_watchdog.h"
#include "PWM.h"

#include <hi_adc.h>

//电子秤
#define GapValue 430                           //影响精度
double hx711_weight = 0;

#define GapValue1 530                           //影响精度
double hx711_weight1 = 0;

unsigned long Sensor_Read(void);
double Get_Sensor_Read(void);

unsigned long Sensor_Read1(void);
double Get_Sensor_Read1(void);

hi_void gpio_init() {
	hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);
}


#define LED_INTERVAL_TIME_US 300000
#define LED_TASK_STACK_SIZE 4096
#define LED_TASK_PRIO 25
#define LED_TEST_GPIO 9 // for hispark_pegasus
#define GPIO_PWM1 6
#define GPIO_PWM2 7

static long long g_iState = 0;

enum LedState {
    LED_ON = 0,
    LED_OFF,
    LED_SPARK,
};

void PWM1_GPIO6_Init(void)
{
    IoSetFunc(GPIO_PWM1,0); /* 将GPIO6定义为普通GPIO功能*/
    IoTGpioSetDir(GPIO_PWM1 , IOT_GPIO_DIR_OUT); /* 设置GPIO6方向为输出*/
}

void PWM1_GPIO7_Init(void)
{
    IoSetFunc(GPIO_PWM2,0); /* 将GPIO6定义为普通GPIO功能*/
    IoTGpioSetDir(GPIO_PWM2 , IOT_GPIO_DIR_OUT); /* 设置GPIO6方向为输出*/
}

enum LedState g_ledState = LED_SPARK;
uint8_t feed = 0;
uint8_t feed_end = 0;
uint8_t iscat = 0;
uint8_t isdog = 0;
hi_u8 text[10];
uint8_t rst = 0;
extern hi_u8 uartBuff[UART_BUFF_SIZE];
uint8_t i=0;
//宠物类别
hi_u8 flag_cat = 0x01;
hi_u8 flag_dog = 0x02;

//是否喂食操作
hi_u8 flag_feed = 0x03;




static void *LedTask(const char *arg)
{
    (void)arg;
    //初始化GPIO口
    IoTGpioInit(LED_TEST_GPIO);
    IoTGpioInit(GPIO_PWM1);
    IoTGpioInit(GPIO_PWM2);
    PWM1_GPIO6_Init();
    PWM1_GPIO7_Init();

    //电子秤
	gpio_init();
	//初始化GPIO11为GPIO输入，为传感器DT引脚
    hi_io_set_func(HI_IO_NAME_GPIO_11, HI_IO_FUNC_GPIO_11_GPIO);
    hi_gpio_set_dir(HI_GPIO_IDX_11,HI_GPIO_DIR_IN);
	//初始化GPIO12为GPIO输出，为传感器SCK引脚
    hi_io_set_func(HI_IO_NAME_GPIO_12, HI_IO_FUNC_GPIO_12_GPIO);
    hi_gpio_set_dir(HI_GPIO_IDX_12,HI_GPIO_DIR_OUT);
    hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);



    //设置IO口输出方向：输出
    IoTGpioSetDir(LED_TEST_GPIO,IOT_GPIO_DIR_OUT);
    while (1) 
    {
        //IoTGpioSetOutputVal(LED_TEST_GPIO, IOT_GPIO_VALUE1);
        //usleep(1000*1000);
        //IoTGpioSetOutputVal(LED_TEST_GPIO, IOT_GPIO_VALUE0);
        //usleep(1000*1000);

        double base_data = 0;
        base_data = Get_Sensor_Read(); //获取基准值

        hx711_weight = (Sensor_Read() - base_data) / GapValue; //获取重量

        //if(hx711_weight > 0) // 大于0时显示
        //{
        //    printf("重量：%f\n",hx711_weight);
        //}



        if(hx711_weight > 800) // 大于0时显示
        {
            printf("重量：%f\n",hx711_weight);
            feed_end = 1;
        }



        if(*uartBuff == flag_feed)
        {
            feed = 1;
        }
        if(*uartBuff == flag_cat)
        {
            iscat = 1;
        }
        if(*uartBuff == flag_dog)
        {
            isdog = 1;
        }
        ///printf("%d\n",*uartBuff);
        //printf("喂食：%d  结束：%d\n",feed,feed_end);
        //printf("猫：%d  狗：%d\n",iscat,isdog);


        //猫的喂食动作
        if(feed==1&&feed_end==0&&iscat==1)
        {
            //喂食行为 测温 监控等
            for(int i = 0; i < 9; i++) 
            {
                IoTGpioSetOutputVal(GPIO_PWM1 , IOT_GPIO_VALUE1); /* GPIO6输出初始值为1*/ 
                hi_udelay(2500);
                IoTGpioSetOutputVal(GPIO_PWM1 , IOT_GPIO_VALUE0); /* GPIO6输出初始值为0*/
                hi_udelay(20000-2500);
            }
            feed = 0;
        }
        else if(feed==1&&feed_end==1&&iscat==1)
        {
            //结束喂食后离开
            for(int i = 0; i < 9; i++) 
            {
                IoTGpioSetOutputVal(GPIO_PWM1 , IOT_GPIO_VALUE1); /* GPIO6输出初始值为1*/ 
                hi_udelay(1500);
                IoTGpioSetOutputVal(GPIO_PWM1 , IOT_GPIO_VALUE0); /* GPIO6输出初始值为0*/
                hi_udelay(20000-1500);
            }
            feed_end = 0;
            *uartBuff = 0;
            iscat = 0;
        }



        //狗的喂食动作
        if(feed==1&&feed_end==0&&isdog==1)
        {
            //喂食行为 测温 监控等
            for(int i = 0; i < 9; i++) 
            {
                IoTGpioSetOutputVal(GPIO_PWM2 , IOT_GPIO_VALUE1); /* GPIO6输出初始值为1*/ 
                hi_udelay(2500);
                IoTGpioSetOutputVal(GPIO_PWM2 , IOT_GPIO_VALUE0); /* GPIO6输出初始值为0*/
                hi_udelay(20000-2500);
            }
            feed = 0;
        }
        else if(feed=10&&feed_end==1&&isdog==1)
        {
            //结束喂食后离开
            for(int i = 0; i < 9; i++) 
            {
                IoTGpioSetOutputVal(GPIO_PWM2 , IOT_GPIO_VALUE1); /* GPIO6输出初始值为1*/ 
                hi_udelay(1500);
                IoTGpioSetOutputVal(GPIO_PWM2 , IOT_GPIO_VALUE0); /* GPIO6输出初始值为0*/
                hi_udelay(20000-1500);
            }
            feed_end = 0;
            *uartBuff = 0;
            isdog = 0;
        }

    }
    return NULL;
}

static void LedExampleEntry(void)
{
    osThreadAttr_t attr;
    IoTWatchDogDisable();
    IoTGpioInit(LED_TEST_GPIO);
    IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT);

    attr.name = "LedTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = LED_TASK_STACK_SIZE;
    attr.priority = LED_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}

SYS_RUN(LedExampleEntry);


unsigned long Sensor_Read(void)
{
	unsigned long value = 0;
	unsigned char i = 0;
	hi_gpio_value input = 0;
	hi_udelay(2);
	//时钟线拉低 空闲时时钟线保持低电位
	hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);
	hi_udelay(2);	
	hi_gpio_get_input_val(HI_IO_NAME_GPIO_11,&input);
	//等待AD转换结束
	while(input)
    {
        hi_gpio_get_input_val(HI_IO_NAME_GPIO_11,&input);
    }
	for(i=0;i<24;i++)
	{
		//时钟线拉高 开始发送时钟脉冲
		hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,1);
		hi_udelay(2);
		//左移位 右侧补零 等待接收数据
		value = value << 1;
		//时钟线拉低
		hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);
		hi_udelay(2);
		//读取一位数据
        hi_gpio_get_input_val(HI_IO_NAME_GPIO_11,&input);
		if(input){
			value ++;
        }
	}
	//第25个脉冲
	hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,1);
	hi_udelay(2);
	value = value^0x800000;	
	//第25个脉冲结束
	hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_12,0);	
	hi_udelay(2);	
	return value;
}


double Get_Sensor_Read(void)
{
  	double sum = 0;    // 为了减小误差，一次取出10个值后求平均值。
  	for (int i = 0; i < 10; i++) // 循环的越多精度越高，当然耗费的时间也越多
    	sum += Sensor_Read();  // 累加
  	return (sum/10); // 求平均值进行均差

}
